//
//  SanitizerCoverage.m
//  SwiftClang
//
//  Created by xchuan on 2025/2/19.
//
#import "XCBinarySort.h"

#import <Foundation/Foundation.h>
#include <stdint.h>
#include <stdio.h>
#include <sanitizer/coverage_interface.h>
#import <dlfcn.h>
#import <libkern/OSAtomic.h>


@implementation XCBinarySort
//定义原子队列
static OSQueueHead symbolQueue = OS_ATOMIC_QUEUE_INIT;

typedef struct {
    void *pc;
    void *next;
} XCNode;

void __sanitizer_cov_trace_pc_guard_init(uint32_t *start,
                                         uint32_t *stop) {
    static uint64_t N;
    if (start == stop || *start) return;
      printf("INIT: %p %p\n", start, stop);
    for (uint32_t *x = start; x < stop; x++)
        *x = ++N;
    printf("函数总个数为: %llu\n", N);
}

void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
    if (!*guard) return;  // Duplicate the guard check.
    
    //获取当前函数返回到上一个调用的地址!!
    void *PC = __builtin_return_address(0);
    
    char PcDescr[1024];
    Dl_info info;
    dladdr(PC, &info);
    NSLog(@"%@", [NSString stringWithUTF8String:info.dli_sname]);
    
    // 创建新的 XCNode
    XCNode *node = malloc(sizeof(XCNode));
    node->next = NULL;
    node->pc = PC;
    
    OSAtomicEnqueue(&symbolQueue, node, offsetof(XCNode, next));
    
    
}

+ (void)getOrderFile {
    
    NSMutableArray *symbolNameArray = @[].mutableCopy;
    NSMutableSet *symbolSet = [NSMutableSet set]; // 用于去重
    
    while (YES) {
        XCNode *dequeuedNode = OSAtomicDequeue(&symbolQueue, offsetof(XCNode, next));
        if (dequeuedNode == NULL) {
            break;
        }
        Dl_info info;
        dladdr(dequeuedNode->pc, &info);
        
        NSString *name = [NSString stringWithUTF8String:info.dli_sname];
        BOOL isOCFunc = [name hasPrefix:@"+["] || [name hasPrefix:@"-["];
        NSString *symbolName = isOCFunc ? name : [@"_" stringByAppendingString:name];
        
        // 检查是否已经存在于集合中以去重
        if (![symbolSet containsObject:symbolName]) {
            [symbolSet addObject:symbolName]; // 添加到集合
            [symbolNameArray insertObject:symbolName atIndex:0]; // 添加到数组
        }
    }
    
    [symbolNameArray removeObject:[NSString stringWithFormat:@"%s", __func__]];
    NSString *symbolStr = [symbolNameArray componentsJoinedByString:@"\n"];
    NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"xc.order"];
    NSData *file = [symbolStr dataUsingEncoding:NSUTF8StringEncoding];
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:file attributes:nil];
    
    NSLog(@"文件生成路径：%@", filePath);
}

@end
